#!/usr/bin/python3
# -*- coding: utf-8 -*-


import os
import requests
import time
from os.path import basename


def _get_cos_token(api_key, build_type, install_type=1, password='', build_update_description='', callback=None):
    """
    获取上传的 token
    """
    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    payload = {
        '_api_key': api_key,  # API Key
        'buildType': build_type,  # 需要上传的应用类型，如果是iOS类型请传ios或ipa，如果是Android类型请传android或apk.
        'buildInstallType': install_type,  # (选填)应用安装方式，值为(1,2,3，默认为1 公开安装)。1：公开安装，2：密码安装，3：邀请安装
        'buildPassword': password,  # (选填) 设置App安装密码，密码为空时默认公开安装
        'buildUpdateDescription': build_update_description,  # (选填) 版本更新描述，请传空字符串，或不传。
    }
    try:
        r = requests.post('https://www.pgyer.com/apiv2/app/getCOSToken', data=payload, headers=headers)
        if r.status_code == requests.codes.ok:
            result = r.json()
            if callback is not None:
                callback(True, result)
        else:
            if callback is not None:
                callback(False, None)
    except Exception as e:
        print('获取token失败,蒲公英服务器暂时无法为您服务： {}'.format(e))


def upload_to_pgyer(path, api_key, build_type, install_type=1, password='', update_description='', callback=None):
    """
    上传到蒲公英
    :param path: 文件路径
    :param api_key: API Key
    :param build_type: build_type,  # 需要上传的应用类型，如果是iOS类型请传ios或ipa，如果是Android类型请传android或apk.
    :param install_type: 应用安装方式，值为(1,2,3)。1：公开，2：密码安装，3：邀请安装。默认为1公开
    :param password: App安装密码
    :param update_description:
    :param callback: 完成上传后的输出回调
    :return: 版本更新描述
    """

    def _progress_callback(transferred):
        progress = round((transferred.bytes_read / transferred.len) * 100, 3)
        print('App包上传进度: {}%'.format(progress), end='\n')

    def get_cos_token_callback(is_success, json):
        if is_success:
            _upload_url = json['data']['endpoint']
            headers = {'enctype': 'multipart/form-data'}
            payload = json['data']['params']
            file_name = basename(path)
            payload.update({'x-cos-meta-file-name': file_name})
            files = {'file': open(path, 'rb')}
            print("开始上传{}到蒲公英......".format(file_name))

            try:
                r = requests.post(_upload_url, data=payload, files=files, headers=headers)
                if r.status_code == 204:
                    print("上传成功，正在获取包处理信息，请稍等...")
                    _get_build_info(api_key=api_key, json=json, callback=callback)
                else:
                    print('HTTPError,Code:{} reason:{}'.format(str(r.status_code), r.reason))
                    if callback is not None:
                        callback(False, None)
            except Exception as e:
                print('上传app包失败,服务器暂时无法为您服务: {}'.format(e))
        else:
            pass

    _get_cos_token(
        api_key=api_key,
        build_type=build_type,
        install_type=install_type,
        password=password,
        build_update_description=update_description,
        callback=get_cos_token_callback,
    )


def _get_build_info(api_key, json, callback=None):
    """
    检测应用是否发布完成，并获取发布应用的信息
    """
    time.sleep(5)  # 先等个几秒，上传完直接获取肯定app是还在处理中~
    response = requests.get('https://www.pgyer.com/apiv2/app/buildInfo', params={
        '_api_key': api_key,
        'buildKey': json['data']['params']['key'],
    })
    if response.status_code == requests.codes.ok:
        result = response.json()
        code = result['code']
        msg = result['message']
        if code == 1247 or code == 1246:  # 1246	应用正在解析、1247 应用正在发布中
            print('蒲公英后台正在发布中： {}'.format(msg))
            _get_build_info(api_key=api_key, json=json, callback=callback)
        elif code == 0:
            print('蒲公英后台发布app安装包成功')
            if callback is not None:
                callback(True, result)
        else:
            print('蒲公英后台发布失败： code {}, {}'.format(code, msg))
            if callback is not None:
                callback(False, result)
    else:
        if callback is not None:
            callback(False, None)


def _upload_complete_callback(is_success, result):
    if is_success:
        _data = result['data']
        _url = _data['buildShortcutUrl'].strip()
        _appVer = _data['buildVersion']
        _buildVer = _data['buildBuildVersion']
        _appBuildURL = 'https://www.pgyer.com/' + _data['buildKey']
        _appQRCodeURL = _data['buildQRCodeURL']
        os.environ['appBuildURL'] = _appBuildURL
        os.environ['appQRCodeURL'] = _appQRCodeURL
        print('appBuildURL:%s,appQRCodeURL:%s' % (_appBuildURL, _appQRCodeURL))
        print('下载链接: https://www.pgyer.com/%s' % _url)
        print('发布版本: %s (build %s)' % (_appVer, _buildVer))
    else:
        print('App包上传失败')


if __name__ == '__main__':
    # /${WORKSPACE}/../sy_flutter_help/${platform}/
    app_path = os.getenv('WORKSPACE') + f"/../sy_flutter_help/{os.environ['platform']}/shiyin_release.{'ipa' if os.environ['platform'] == 'iOS' else 'apk'}"  # App包路径
    pgyer_api_key = '99a42f0859d3590db7b9955d52f72b66'  # 蒲公英API KEY
    platform = os.environ['platform']  # 应用类型，如果是iOS类型请传ios或ipa，如果是Android类型请传android或apk.
    update_descr = 'Uploaded by jenkins upload-pgyer api python script'  # 版本更新描述

    upload_to_pgyer(
        path=app_path,
        api_key=pgyer_api_key,
        build_type=platform,
        update_description=update_descr,
        callback=_upload_complete_callback
    )
